﻿using System;
using System.Text;
using AutoMapper;
using DataManageSystem.Common;
using DataManageSystem.Data;
using DataManageSystem.Exceptions;
using DataManageSystem.Models;
using DataManageSystem.Models.Dto;
using DataManageSystem.Models.LimsModels;

namespace DataManageSystem.Services
{
    public class MonitorDevServices
    {
        private readonly ApplicationDbContext _context;
        private readonly DeviceDbContext dbContext;
        private readonly IMapper _mapper;
        private readonly IServiceScopeFactory _scopeFactory;

        public MonitorDevServices(
            ApplicationDbContext context,
            DeviceDbContext dbContext,
            IMapper mapper,
            IServiceScopeFactory scopeFactory
        )
        {
            _context = context;
            dbContext = dbContext;
            _mapper = mapper;
            _scopeFactory = scopeFactory;
        }

        /// <summary>
        /// 分页查询监控设备
        /// </summary>
        public Result SelectByPage(int page, int size, string? address, string? type)
        {
            var query = _context.MonitorDevs.AsQueryable();

            if (!string.IsNullOrEmpty(address))
            {
                query = query.Where(m => m.Address.Contains(address));
            }

            if (!string.IsNullOrEmpty(type))
            {
                query = query.Where(m => m.Type.Contains(type));
            }

            int total = query.Count();
            var monitors = query
                .OrderByDescending(m => m.Id)
                .Skip((page - 1) * size)
                .Take(size)
                .ToList();
            return Result.Success(monitors, total);
        }

        /// <summary>
        /// 添加监控设备
        /// </summary>
        public void Add(MonitorDevDto monitorDevDto)
        {
            if (
                string.IsNullOrEmpty(monitorDevDto.Address)
                || string.IsNullOrEmpty(monitorDevDto.Type)
            )
            {
                throw new ServiceException("设备地址和类型不能为空");
            }

            var monitorDev = _mapper.Map<MonitorDev>(monitorDevDto);
            monitorDev.RtspUrl = GenerateRtspUrl(monitorDev);

            _context.MonitorDevs.Add(monitorDev);
            _context.SaveChanges();
        }

        /// <summary>
        /// 更新监控设备信息
        /// </summary>
        public void Update(MonitorDevDto monitorDevDto)
        {
            if (monitorDevDto == null || monitorDevDto.Id <= 0)
            {
                throw new ServiceException("无效的设备信息");
            }

            var existMonitorDev = _context.MonitorDevs.FirstOrDefault(m =>
                m.Id == monitorDevDto.Id
            );
            if (existMonitorDev == null)
            {
                throw new ServiceException("设备不存在");
            }

            _mapper.Map(monitorDevDto, existMonitorDev);
            existMonitorDev.RtspUrl = GenerateRtspUrl(existMonitorDev);

            _context.MonitorDevs.Update(existMonitorDev);
            _context.SaveChanges();
        }

        /// <summary>
        /// 根据 ID 获取监控设备
        /// </summary>
        public MonitorDev? GetById(int id)
        {
            return _context.MonitorDevs.FirstOrDefault(m => m.Id == id);
        }

        /// <summary>
        /// 删除监控设备
        /// </summary>
        public void Delete(int id)
        {
            var monitor = _context.MonitorDevs.FirstOrDefault(m => m.Id == id);
            if (monitor != null)
            {
                _context.MonitorDevs.Remove(monitor);
                _context.SaveChanges();
            }
            else
            {
                throw new ServiceException("设备不存在");
            }
        }

        /// <summary>
        /// 生成 RTSP 地址
        /// </summary>
        private string GenerateRtspUrl(MonitorDev monitor)
        {
            if (
                string.IsNullOrEmpty(monitor.Address)
                || string.IsNullOrEmpty(monitor.Port)
                || string.IsNullOrEmpty(monitor.Account)
                || string.IsNullOrEmpty(monitor.Password)
                || string.IsNullOrEmpty(monitor.Type)
            )
            {
                return string.Empty;
            }

            switch (monitor.Type.ToLower())
            {
                case "海康":
                    return $"rtsp://{monitor.Account}:{monitor.Password}@{monitor.Address}:{monitor.Port}/Streaming/Channels/1";
                case "大华":
                    return $"rtsp://{monitor.Account}:{monitor.Password}@{monitor.Address}:{monitor.Port}/cam/realmonitor?channel=1&subtype=0";
                default:
                    return $"rtsp://{monitor.Account}:{monitor.Password}@{monitor.Address}:{monitor.Port}/";
            }
        }

        public string Migration()
        {
            using (var scope = _scopeFactory.CreateScope())
            {
                var dbContext = scope.ServiceProvider.GetRequiredService<DeviceDbContext>();

                // 获取已存在的 MonitorCode（去重）
                var existingMonitorCodes = dbContext
                    .TSafeMonitors.Select(m => m.MonitorCode)
                    .ToHashSet();

                // 过滤未迁移的设备
                var monitorDevs = _context
                    .MonitorDevs.Where(m => !existingMonitorCodes.Contains(m.Area))
                    .ToList();

                if (!monitorDevs.Any())
                    return "没有需要迁移的数据"; // 如果没有新设备，直接返回

                // 准备迁移数据
                var safeMonitors = monitorDevs
                    .Select(m => new TSafeMonitor
                    {
                        Guid = Guid.NewGuid().ToString(),
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now,
                        CreateUser = "lkc",
                        UpdateUser = "lkc",
                        Valid = 1,
                        MonitorCode = m.Area,
                        Location = m.Area,
                        DeptGuid = null,
                        Address = m.Address,
                        Type = null,
                        RtspUrl =
                            $"rtsp://{m.Account}:{m.Password}@{m.Address}:{m.Port}/cam/realmonitor?channel=1&subtype=0",
                        TargetUrl = $"http://127.0.0.1:8888/{m.UrlId}",
                        MonitorName = null,
                        Port = null,
                    })
                    .ToList();

                // 批量写入数据库
                dbContext.TSafeMonitors.AddRange(safeMonitors);
                dbContext.SaveChanges();

                // 生成 YAML 配置文件
                return GenerateYamlConfig(monitorDevs);
            }
        }

        private string GenerateYamlConfig(List<MonitorDev> monitors)
        {
            string filePath = "D:\\config.yaml";
            //string filePath = "E:\\config.yaml"; // 配置文件路径
            var sb = new StringBuilder();

            foreach (var monitor in monitors)
            {
                string account = monitor.Account;
                string password = monitor.Password;
                string address = monitor.Address;
                string port = monitor.Port;

                sb.AppendLine($"  \"{monitor.UrlId}\":");
                sb.AppendLine(
                    $"    source: rtsp://{account}:{password}@{address}:{port}/cam/realmonitor?channel=1&subtype=0"
                );
                sb.AppendLine($"    sourceOnDemand: yes");
                sb.AppendLine($"    rtspTransport: tcp");
            }

            Console.WriteLine(sb.ToString());
            // 写入文件
            File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8);
            return $"数据迁移成功，配置文件地址{filePath}";
        }
    }
}
